import dieReward_component from "../../component/dieReward_component";
import talent_component from "../../component/talent_component";
import gameCfg from "../../gameCfg";
import { config, configKey } from "../../config";
import { DataSkill, Item, panel_common } from "../../shared/face/index";
import { qualityName, ItemType } from "../../shared/face/enums";
import common from "../tool/common";
import { ComType } from "../tool/component";
import { Icard } from "../tool/Icard";
import type { Skill, SkillUse } from "../rpg/types";
import SkManager from "../rpg/skill/SkManager";
import { IBodyCreateConfig, killLog } from "../rpg/types";
import { BaseBody } from "../rpg/entity/body_base";
import enemy from "../rpg/entity/enemy";
import { DataEquip } from "../../shared/face";
import { quality } from "../../shared/face/enums";
import Counter, { CounterKey } from "./Counter";
import EquipManage, { EquipTemplate } from "./EquipManage";

import { Icard2 } from "../tool/Icard2";
import sdk from '../index';
import { equipService } from "../../service/EquipService";
import { SkillManager } from "../rpg";
interface createData {
    type: ItemType,
    id: string,
    count: number
}
class PropManage {
    constructor() {

    }
    /**
     * 获取道具 市场id
     * @returns 
     */
    getItemMarketLogKey(data: Item) {
        let key = `${data.type}-`;
        switch (data.type) {
            case ItemType.装备:
                key += data.name;
                break;
            case ItemType.资源:
                key += data.id;
                break;
            default:
                key = `${data.type}-${data.id}`;
                break;
        }
        return key;
    }
    createProp(data: createData): Item {
        let item = this.createItem();
        item.count = data.count;
        let _cfg: any;
        switch (data.type) {
            case ItemType.道具:
                _cfg = config.get(configKey.道具表)?.get(data.id);
                if (!_cfg) {
                    console.error(`道具配置不存在: ${data.id}`);
                    throw new Error(`道具配置不存在: ${data.id}`);
                }
                item.id = _cfg.id;
                item.type = ItemType.道具;
                item.quality = _cfg.quality;
                item.name = _cfg.name;
                item.desc = _cfg.desc;
                item.emoji = _cfg.emoji;
                item.data = _cfg.data;
                item.stacking = true; // 道具类物品可以堆叠
                break;
            case ItemType.装备:
                _cfg = EquipManage.getTemplateById(data.id) as EquipTemplate;
                if (!_cfg) {
                    // 随机获取一个装备模板
                    _cfg = EquipManage.getRandomTemplate();
                    if (!_cfg) {
                        console.error('没有可用的装备模板，无法生成装备');
                        throw new Error('没有可用的装备模板，无法生成装备');
                    }
                }
                item.type = ItemType.装备;
                item.name = _cfg.name;
                item.desc = _cfg.desc;
                item.count = 1;
                item.data = this.createEquip(_cfg);
                item.id = item.data.id;
                item.quality = item.data.quality;
                item.emoji = _cfg.emoji;
                item.icon = _cfg.icon;
                item.stacking = false; // 装备类物品不可堆叠
                break;
            case ItemType.资源:
                _cfg = config.get(configKey.资源表)?.get(data.id);
                if (!_cfg) {
                    console.error(`资源配置不存在: ${data.id}`);
                    throw new Error(`资源配置不存在: ${data.id}`);
                }
                item.quality = quality.F;
                item.id = _cfg.id;
                item.type = ItemType.资源;
                item.name = _cfg.name;
                item.desc = _cfg.desc;
                item.emoji = _cfg.emoji;
                item.stacking = true; // 资源类物品可以堆叠
                break;
            case ItemType.消耗品:
                _cfg = config.get(configKey.消耗品表)?.get(data.id);
                if (!_cfg) {
                    console.error(`消耗品配置不存在: ${data.id}`);
                    throw new Error(`消耗品配置不存在: ${data.id}`);
                }
                item.id = _cfg.id;
                item.type = ItemType.消耗品;
                item.tag = _cfg.tag;
                item.stacking = _cfg.stacking;
                item.stacking_use = _cfg.stackingUse;
                item.name = _cfg.name;
                item.desc = _cfg.desc;
                item.emoji = _cfg.emoji;
                item.quality = _cfg.quality || quality.F;
                item.data = {
                    funcName: _cfg.funcName,
                    funcData: _cfg.funcData
                };
                break;
            default:
                console.error(`未知的道具类型: ${data.type}`);
                debugger
                break;
        }
        return item!;
    }
    /**
     * 自定义创建道具
     * @param data 
     * @returns 
     */
    createProp_customize(data:Item):Item{
        // 拷贝data
        let item = {...data};
        item.stacking = data.stacking;
        item.stacking_use = data.stacking_use;
        item.count = data.count;
        item.id = data.id;
        item.type = ItemType.消耗品;
        item.name = data.name;
        item.desc = data.desc;
        item.emoji = data.emoji;
        item.quality = data.quality;
        item.icon = data.icon;
        item.data = data.data;
        /**
         * data
         * funcName
         * funcData
         */

        return item;
    }
    createPet(data: IBodyCreateConfig) {
        let item: IBodyCreateConfig = {
            url: data.url,
            emoji: data.emoji,
            name: data.name || '随从',
            level: data.level || 1,
            skill: data.skill || []
        }
        return item;
    }
    private createEquip(data: any) {
        let item: DataEquip = {
            uuid: sdk.tool.common.uuid,
            strengthenLevel:1,
            count: 1,
            id: Counter.get(CounterKey.装备ID),
            icon: data.icon || "none",
            sys: data.sys || "魔幻本质",
            type: data.type || "修真",
            job: data.job || "剑修",
            quality: Counter.getQuality(),
            emoji: "🗡️",
            source: data.source || "修真",
            name: data.name || "测试装备",
            solt_type: data.solt_type || "测试位置",
            desc: data.desc || "测试描述",
            creator: data.creator || "sys",
            attribute: [],
            skill: [],
            createTime: Date.now(),
            updateTime: Date.now()
        }
        item.attribute = this.createEquipAttribute(item.sys, item.type, item.job, item.solt_type, item.quality);
        // 废弃
        // if (data.skill) {
        //     item.skill = this.createEquipSkill(data.skill, item.quality)
        // }
        return item;
    }
     createEquipAttribute(sys: string, type: string, job: string, solt_type: string, quality: quality) {
        let list = Array.from((config.get(configKey.配置_装备属性) as Map<string, any>).values())
            .filter(item => item.sys == sys && item.type == type && item.job == job && item.solt == solt_type)
        if(list.length == 0){
            return [];
        }
        let item = list[sdk.tool.common.random(0, list.length - 1)];
        let _temp = [];

        if (item.attribute.length) {
            for (let i = 0; i < item.attribute.length; i++) {
                let e = item.attribute[i];
                let val = Number(e.val);
                val += sdk.tool.common.random(val * (quality), val * (quality + 1));
                val = Math.ceil(gameCfg.baseLeve * val);
                _temp.push({ key: e.key, val: val })
            }
        } else {
            let e = item.attribute;
            let val = Number(e.val);
            val += sdk.tool.common.random(val * (quality), val * (quality + 1));
            val = Math.ceil(gameCfg.baseLeve * val);
            _temp.push({ key: e.key, val: val })
        }

        return _temp;
    }
    /**
     * 将装备转换为道具
     * @param equip 
     * @returns 
     */
    cover_equipToItem(equip: DataEquip): Item {
        let item: Item = {
            quality: equip.quality,
            uuid: sdk.tool.common.uuid,
            emoji: equip.emoji,
            id: equip.id,
            stacking: false,
            stacking_use: false,
            tag: '装备',
            name: equip.name,
            desc: equip.desc,
            type: ItemType.装备,
            count: 1,
            icon: '',
            data: equip
        }
        return item;
    }
    // 创建一个Item数据模板
    private createItem(): Item {
        return {
            quality: quality.F,
            uuid: sdk.tool.common.uuid,
            emoji: '🙂',
            id: '',
            name: '',
            desc: '',
            type: ItemType.资源,
            count: 0,
            data: {},
            icon: gameCfg.defaultIcon
        }
    }
    // 根据配置表中的奖励策略，返回奖励
    PolicyReward_击杀(policy: string, log: killLog, mapId?: string) {
        let _cfg = config.get(`${configKey.通用击杀奖励}_通用击杀`) as Map<string, any>;
        let _cfgItem = _cfg.get(policy);
        
        let _reward = this.coverEval(_cfgItem.rewardEval, log, mapId);
        let fixReward = this.coverFix(_cfgItem.rewardFix, mapId);
        _reward.push(...fixReward);
        console.log(`通用击杀奖励 - eval数量: ${this.coverEval(_cfgItem.rewardEval, log, mapId).length}, fix数量: ${fixReward.length}`);

        if (log.target.getBody() instanceof enemy) {
            let dieCom = log.target.getComponent(ComType.死亡掉落) as dieReward_component;
            let _dieCfg = config.get(dieCom.cfg_table) as Map<string, any>;
            let _dieCfgItem = _dieCfg.get(dieCom.cfg_id);
            let dieEvalReward = this.coverEval(_dieCfgItem.rewardEval, log, mapId);
            let dieFixReward = this.coverFix(_dieCfgItem.rewardFix, mapId);
            _reward.push(...dieEvalReward);
            _reward.push(...dieFixReward);
            console.log(`敌人死亡掉落 - eval数量: ${dieEvalReward.length}, fix数量: ${dieFixReward.length}`);
        }
        if (mapId) {
            _cfg = config.get(`${configKey.通用击杀奖励}_地图_${mapId}`) as Map<string, any>;
            _cfgItem = _cfg.get(policy);
            let mapEvalReward = this.coverEval(_cfgItem.rewardEval, log, mapId);
            let mapFixReward = this.coverFix(_cfgItem.rewardFix, mapId);
            _reward.push(...mapEvalReward);
            _reward.push(...mapFixReward);
            console.log(`地图特定奖励 - eval数量: ${mapEvalReward.length}, fix数量: ${mapFixReward.length}`);
        }
        
        console.log(`PolicyReward_击杀 - 策略: ${policy}, 地图: ${mapId}, 奖励数量: ${_reward.length}`);
        if (_reward.length === 0) {
            console.log(`警告: PolicyReward_击杀 返回空奖励数组`);
        }
        return _reward;
    }
    private coverEval(data: any | any[], v: any, mapId?: string) {
        if (!data) {
            return []
        }
        let cfg: any[] = [];
        let returnData: any[] = [];
        if (Array.isArray(data)) {
            cfg = data;
        } else {
            cfg = [data];
        }
        cfg.forEach(item => {
            if (!item.id) {
                return;
            }
            let id = isNaN(Number(item.id)) ? item.id : Number(item.id);
            
            let max, min;
            try {
                // 在eval中提供必要的变量
                const killLog = v; // killLog
                const target = killLog.target;
                const unit = killLog.unit;
                const round = killLog.round;
                
                max = eval(item.max);
                min = eval(item.min);
            } catch (error) {
                console.error(`coverEval - 表达式求值失败: min=${item.min}, max=${item.max}, error=${error}`);
                return; // 跳过这个奖励
            }
            
            let _id = id;
            if (item.type == ItemType.装备 && mapId) {
                _id = `${mapId}_${id}`
            }
            
            try {
                let _prop = this.createProp({
                    type: item.type,
                    id: _id.toString(),
                    count: Math.ceil(sdk.tool.common.random(min, max))
                })
                returnData.push(_prop);
            } catch (error) {
                console.error(`coverEval - 创建道具失败: ${error}`);
            }
        });
        return returnData;
    }
    private coverFix(data: any | any[], mapId?: string) {
        if (!data) {
            return []
        }
        let cfg: any[] = [];
        let returnData: any[] = [];
        if (Array.isArray(data)) {
            cfg = data;
        } else {
            cfg = [data];
        }
        cfg.forEach(item => {
            if (!item.id) {
                return;
            }
            
            let max = Number(item.max);
            let min = Number(item.min);
            let _id = item.id;
            if (item.type == ItemType.装备 && mapId) {
                _id = `${mapId}_${_id}`
            }
            
            try {
                let _prop = this.createProp({
                    type: item.type,
                    id: _id,
                    count: Math.ceil(sdk.tool.common.random(min, max))
                })
                returnData.push(_prop);
            } catch (error) {
                console.error(`coverFix - 创建道具失败: ${error}`);
            }
        });
        return returnData;
    }
    /**
     * 盲盒奖励
     * @param data 
     * @returns 
     */
    coverBoxGift(data: any | any[], count: number = 1) {
        let random = sdk.tool.common.random;
        let randomSk = this.randomSk;
        let 随机装备ID = EquipManage.getRandomTemplateId();
        if (!data || count < 1) {
            return []
        }
        let cfg: any[] = [];
        let returnData: Item[] = [];
        if (Array.isArray(data)) {
            cfg = data;
        } else {
            cfg = [data];
        }
        // 明确声明权重选项类型

        let weightOptions: any[] = [];
        let totalWeight = 0;

        for (const item of cfg) {
            if (!item?.id) continue;

            const weight = Number(item.weight) || 0;
            if (weight > 0) {
                weightOptions.push({
                    ...item,
                    weight,
                    start: totalWeight,
                    end: totalWeight + weight
                });
                totalWeight += weight;
            }
        }

        if (totalWeight > 0) {
            const randomValues = Array.from({ length: count },
                () => sdk.tool.common.random(0, totalWeight)
            );

            randomValues.forEach(randomVal => {
                const selected = weightOptions.find(opt =>
                    randomVal >= opt.start && randomVal < opt.end
                );

                if (selected) {
                    const id = selected.func == 'eval' ? eval(selected.id) : selected.id;
                    const max = selected.func == 'eval' ? eval(selected.max) : Number(selected.max);
                    const min = selected.func == 'eval' ? eval(selected.min) : Number(selected.min);
                    const _prop = this.createProp({
                        type: selected.type,
                        id: id.toString(),
                        count: Math.ceil(sdk.tool.common.random(min, max))
                    });
                    returnData.push(_prop);
                }
            });
        }

        return returnData;
    }
    private randomSk() {
        let _quality = sdk.tool.common.randomWeight({ min: quality.F, max: quality.S });
        let sk = SkManager.randomSk_shop(_quality);
        if (sk) {
            return sk.id;
        }
        return null;
    }
    client_lookitemV2(item: Item, _card?: Icard2) {
        console.log('::查看道具', item);
        let card = _card || sdk.tool.card.create2();

        switch (item.type) {
            case ItemType.装备:
                this.client_equip(item.data as DataEquip, card);
                break;
            case ItemType.道具:
            // case ItemType.资源:
                card.icon(item.emoji,item.icon);
                card.l('名称', item.name)
                card.l('描述', item.desc)
                break;
            case ItemType.消耗品:
                card.icon(item.emoji,item.icon);
                card.l('名称', item.name)
                card.l('类型', item.tag)
                card.l('品质', Object.values(qualityName)[item.quality])
                card.l('描述', item.desc)
                break;
            default:
                return card;
        }
        return card;
    }
    /**
     * V2查看装备
     * @param equip 
     * @param card 
     */
    client_equip(equip: DataEquip, card: Icard2) {
        card.icon(equip.emoji, equip.icon);
        card.l('编号', `#${equip.id}#UID${equip.creator}(${sdk.user.getNameByUid(equip.creator)})`)
        card.l('名称', `${equip.name} +${equip.strengthenLevel}`)
        card.l('品质', Object.values(qualityName)[equip.quality])

        card.l('体系', `${equip.sys}-${equip.type}-${equip.job}`)
        card.l('装备类型', `${equip.solt_type}`)
        // 属性
        let _att = '';
        equip.attribute.forEach((item: any) => {
            if(equip.strengthenLevel > 1){
                _att += `${item.key}:${item.val} +${equipService.getStrengthenMultiplier(equip.strengthenLevel)}\n`
            }else{
                _att += `${item.key}:${item.val}\n`
            }
        })
        card.l('属性', _att)
        if (equip.skill.length > 0) {
            // 技能
            let skillStr = '';
            equip.skill.forEach((item: DataSkill) => {
                const skill = SkillManager.getSkillById(item.skillId);
                if (skill) {
                    skillStr += `Lv.${item.level} ${item.reName || skill.name}\n`
                }
            })
            card.l('技能', skillStr)
        }
        card.l('来源', equip.source)
        card.l('描述', equip.desc)
    }
    /**
     * V2查看血统
     * @param talent 
     * @param card 
     * @param Preview 是否预览
     */
    client_talent(id: string, self: BaseBody | undefined, card: Icard2, Preview: boolean = true) {
        let cfg = config.get(configKey.配置_血统)?.get(id);
        card.icon(cfg.emoji, cfg.icon);
        card.l('体系', cfg.sys)
        if (!Preview && self) {
            let com_talent = self.getComponent(ComType.血统) as talent_component;
            let item = com_talent.getItem(id);
            if (item) {
                let leve = '';
                let _table = cfg.table.split('\n');
                if (cfg.leve == _table.length) {
                    leve = '已满级';
                } else {
                    leve = item.level.toString();
                }
                card.l('等级', leve)
                card.l('经验', `${item.exp_now}/${item.exp_max}`)
                card.l('称号', _table[item.level - 1])
                card.l('品质', Object.values(qualityName)[item.quality])
            }
            card.l('描述', cfg.desc)
        } else {
            card.l('名称', cfg.name)
            card.l('品质', Object.values(qualityName)[quality.SSR])
            card.l('描述', `使用将获得F级·${cfg.name}血统,如拥有血统,则获少量血统经验(有低概率提升血统品质)。`)
        }
        let _att = '';
        cfg.attribute.forEach((item: any) => {
            _att += `${item.key}:${item.val}\n`
        })
        card.l('加成', _att)
    }


}

export default new PropManage();
